import React, { MouseEventHandler, useEffect, useState } from "react";
import { useComponentsStore, Component } from "../../stores/components";
import { useComponentConfigStore } from "../..//stores/component-config";
import { HoverMask } from "./HoverMask";
import { SelectedMask  } from "./SelectedMask";


export function EditArea() {

    const { components, curComponentId, setCurComponentId } = useComponentsStore();
    const { componentConfig } = useComponentConfigStore();
    const [hoverComponentId, setHoverComponentId] = useState<number>()

    const renderComponents = (components: Component[]): React.ReactNode => {
        return components.map((component: Component)=>{
            const config = componentConfig?.[component.name]
            if(!config?.dev) return null;

            return React.createElement(config.dev, 
                { 
                    key: component.id,
                    id: component.id,
                    name: component.name,
                    styles: component.styles,
                    ...config.defaultProps,
                    ...component.props
                },
                renderComponents(component.children || [])
            )
        })
    }

    const handleMouseOver: MouseEventHandler = (e)=>{ 
        // React中的事件都是合成事件（即：React底层对原生事件做了进一步的处理，有的原生事件的属性它没有）同时，为了方便开发者使用原生事件，React将原生的事件放到了nativeEvent对象中
        console.log(e)
        console.log(e.nativeEvent) 
        const path = e.nativeEvent.composedPath();

        for(let i=0; i<path.length; i++) {
            const ele = path[i] as HTMLElement;
            const componentId = ele.dataset?.componentId;
            if(componentId) {
                setHoverComponentId(+componentId)
                return
            }
        }
    }

    const handleClick: MouseEventHandler = (e)=>{
        const path = e.nativeEvent.composedPath();

        for(let i=0; i<path.length; i++) {
            const ele = path[i] as HTMLElement;
            const componentId = ele.dataset?.componentId;
            if(componentId) {
                setCurComponentId(+componentId);
                return;
            }
        }
    }

    // 测试低代码核心之一数据结构是否设计的正确
    /* useEffect(()=>{
        addComponent({
            id: 222,
            name: 'Container',
            props: {},
            children: []
        }, 1)
        addComponent({
            id: 333,
            name: 'Button',
            props: {
                text: '无敌'
            },
            children: []
        }, 222)
    }, []) */

    /* 我们将hover和click绑定在编辑器根组件上，利用事件冒泡，这样就不用一个个给物料组件绑定hover，click事件了 */
    return <div className="h-[100%] edit-area" onMouseOver={handleMouseOver} onMouseLeave={()=>{setHoverComponentId(undefined)}} onClick={handleClick}>
        {/* <pre>
            { JSON.stringify(components, null, 2) }
        </pre> */}
        { renderComponents(components) }
        {/* 我们现在对hover代码进行一下优化，审查元素时会发现 会创建多个 .wrapper 的div，这是因为 伴随着hoverComponentId值的变化 HoverMask组件会不对的创建与卸载，这样很影响性能，我们对这段代码优化一下 */}
        {/* {hoverComponentId &&  <HoverMask containerClassName="edit-area" componentId={hoverComponentId} />} */}
        { hoverComponentId && hoverComponentId !== curComponentId && <HoverMask containerClassName="edit-area" componentId={hoverComponentId} portalWrapperClassName="portal-wrapper" /> }
        { curComponentId && <SelectedMask componentId={curComponentId} containerClassName="edit-area" portalWrapperClassName="portal-wrapper" /> }
        <div className="portal-wrapper"></div>
    </div>
}